package com.zxy.config;

import com.zxy.bean.Car;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

/**
 * bean的生命周期：
 *
 * bean创建---初始化---销毁过程
 *
 *   构造 （对象创建）
 *   单实例  在容器启动的时候创建对象
 *   多实例  在每次获取的时候创建对象
 *
 *       BeanPostProcessor。postProcessBeforeInitialization
 *  初始化 ： 对象创建完成，并赋值好调用初始化方法。。
 *       BeanPostProcessor。postProcessAfterInitialization
 *
 *
 * 容器管理bean的生命周期：
 * 我们可以自定义初始化和销毁方法，容器在bean进行到当前生命周期的时候类调用我们自定义从初始化和销毁方法
 * 1）指定初始化和销毁方法
 * bean中的init-method="" destroy-method=""
 * 2）通过让bean实现InitializingBean（定义初始化逻辑）
 *              实现DisposableBean（定义销毁逻辑）
 *3）可以使用JSR250；
 *          @PostConstruct 在bean创建完成并且属性赋值完成，来执行初始化方法
 *          @PreDestroy  在容器销毁bean之前通知我们进行清理工作
 * 4）BeanPostProcessor: bean 的后置处理器
 *                      在bean初始化前后进行一些处理工作
 *                      postProcessBeforeInitialization：在初始化之前工作
 *                      postProcessAfterInitialization： 在初始化之后工作
 *
 *BeanPostProcessor原理
 * 遍历得到容器中所有的BeanPostProcessor:挨个执行BeforeInitialization
 * 一旦返回null ，跳出for循环
 *populateBean(beanName,mbd,instanceWrapper)给bean进行属性赋值
 * {
 * applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName)
 * invokeInitMethods(beanName, wrappedBean, mbd);执行自定义初始化
 * applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
 * }
 *
 * spring底层对beanPostProcessor的使用
 *          bean赋值，注入其他组件@Autowired 生命周期的注解功能@Async，xxx   都是BeanPostProcessor中实现
 */
@ComponentScan("com.zxy.bean")
@Configuration
public class MainConfigOfLifeCycle {
    // 指定初始化和销毁方法
    //初始化 对象创建完成，并赋值好，调用初始化方法
    //在容器关闭的时候进行销毁
    /**
     * 销毁
     * 单实例：容器关闭的时候
     * 多实例： 容器不会管理这个bean：容器不会调用销毁方法  可以手动调用
     **/

    //@Scope("prototype")
    @Bean(initMethod = "init", destroyMethod = "destroy")
    public Car car() {
        return new Car();
    }
}
